package Thread;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * 多线程创建方式三：实现Callable接口
 * 方法一、二存在一个问题：假如线程执行完毕后有一些数据要返回，他们重写的run方法均不能直接返回结果（void类型）
 * 解决方法：JDK5.0提供的Callable接口和FutureTask类（多线程创建方式三）
 * 1.创建任务对象
 *   定义一个类实现Callable接口，重写Call方法，封装要做的事情和要返回的数据
 *   把Callable接口类型的对象封装成FutureTask（线程任务对象）
 * 2.把线程任务对象交给Thread对象
 * 3.调用线程对象的start方法启动线程
 * 4.线程执行完毕后，通过FutureTask对象的get方法获取线程任务执行的结果
 * 未来任务对象的作用：
 * 1.是一个任务对象，实现了Runnable对象
 * 2.可以在线程执行完毕后用未来任务对象的get方法获取线程任务执行的结果
 *注：如果代码执行到get方法，线程还没执行完毕，则会暂停，等待线程执行完毕
 * FutureTask的API
 * 构造器：public FutureTask<>(Callable) 把Callable对象封装成FutureTask对象
 * 方法：public V get() throws Exception 获取线程执行call方法返回的结果
 * 线程创建方式三的优缺点：
 * 优点：1.线程任务对象只是实现接口，可以继续继承类和实现接口，扩展性强
 *      2.可以在线程执行完毕后获取线程执行的结果
 * 缺点：编码相对复杂
 */
public class ThreadTest3 {
    public static void main(String[] args) throws Exception, InterruptedException {
        Callable<String> callable = new MyCallable(100);
        FutureTask<String> f1 = new FutureTask<>(callable);
        new Thread(f1).start();
        String rs = f1.get();
        System.out.println(rs);
    }
}
